#pragma once

#include "map_types.h"
#include <QString>
#include <QHash>
#include <memory>

namespace kernel {

class Map {
public:
    Map() = default;
    ~Map() = default;

    // Core map data access
    const MapHeader& getHeader() const { return header_; }
    const QList<StationPoint>& getStationPoints() const { return stationPoints_; }
    const QList<BezierPath>& getBezierPaths() const { return bezierPaths_; }
    const QList<ArcPath>& getArcPaths() const { return arcPaths_; }
    const QList<StraightPath>& getStraightPaths() const { return straightPaths_; }
    const QList<Position>& getNormalPoints() const { return normalPoints_; }
    const QList<Area>& getAreas() const { return areas_; }
    const QList<Area>& getBlockAreas() const { return blockAreas_; }

    // Business logic methods
    QString getStationName(int stationNumber) const;
    StationPoint* findStationPoint(const QString& name);
    const StationPoint* findStationPoint(const QString& name) const;
    BezierPath* findBezierPath(const QString& pathName);
    double calculateBezierLength(const BezierPath& path, int pointCount = 10) const;
    Position calculateBezierPoint(double t, const BezierPath& path) const;

    // Map validation
    bool isValid() const;

    // For MapService to populate data
    void setHeader(const MapHeader& header) { header_ = header; }
    void addStationPoint(const StationPoint& point);
    void addBezierPath(const BezierPath& path);
    void addArcPath(const ArcPath& path);
    void addStraightPath(const StraightPath& path);
    void addNormalPoint(const Position& point) { normalPoints_.append(point); }
    void addArea(const Area& area) { areas_.append(area); }
    void addBlockArea(const Area& area) { blockAreas_.append(area); }

    void clear();
    void buildIndexes();

private:
    MapHeader header_;
    QList<StationPoint> stationPoints_;
    QList<BezierPath> bezierPaths_;
    QList<ArcPath> arcPaths_;
    QList<StraightPath> straightPaths_;
    QList<Position> normalPoints_;
    QList<Area> areas_;
    QList<Area> blockAreas_;

    // Hash indexes for fast lookup
    QHash<int, QString> stationNameHash_;
    QHash<QString, int> stationIndexHash_;
    QHash<QString, int> bezierPathIndexHash_;

    Position calculateBezierPoint(double t, const Position& p0, const Position& p1,
                                 const Position& p2, const Position& p3) const;
};

} // namespace kernel